#include "link_stack.h"
#include <stdexcept>
using namespace std;

/*
 *Construct the stack
 */
template <class Object>
Stack<Object>::Stack()
{
	topofStack = NULL;
}

/*
 *Destructor
 */
template <class Object>
Stack<Object>::~Stack()
{
	makeEmpty();
}

template <class Object>
bool Stack<Object>::isFull() const
{
	return false;
}

template <class Object>
bool Stack<Object>::isEmpty() const
{
	return topofStack == NULL;
}

template <class Object>
void Stack<Object>::makeEmpty()
{
	while(!isEmpty())
		pop();
}

template <class Object>
void Stack<Object>::push(const Object &x)
{
	topofStack = new ListNode(x, topofStack);
}

template <class Object>
const Object & Stack<Object>::top() const
{
	if (isEmpty())
		throw range_error("stack empty");		
		//throw underflow();
	return topofStack->element;
}

template <class Object>
void Stack<Object>::pop()
{
	if (isEmpty())
		throw range_error("stack empty");		
		//throw underflow();

	ListNode *oldTop = topofStack;
	topofStack = topofStack->next;
	delete oldTop;
}

template <class Object>
Object Stack<Object>::topAndPop()
{
	Object topItem = top();
	pop();
	return topItem;
}

template <class Object>
const Stack<Object> & Stack<Object>::
operator=(const Stack<Object> &rhs)
{
	if (this != &rhs) {
		makeEmpty();
		if (rhs.isEmpty())
			return *this;
	
		ListNode *rptr = rhs.topofStack;
		ListNode *ptr = new ListNode(rptr->element);
		topofStack = ptr;

		for (rptr = rptr->next; rptr != NULL; rptr = rptr->next)
			ptr = ptr->next = new ListNode(rptr->element);
	}
	return *this;
}

template <class Object>
Stack<Object>::Stack(const Stack<Object> &rhs)
{
	topofStack = NULL;
	*this = rhs;
}
